package cn.lliiooll;

import net.milkbowl.vault.economy.Economy;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.Player;
import org.bukkit.plugin.RegisteredServiceProvider;
import org.bukkit.plugin.java.JavaPlugin;

import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.UUID;

public class PTP extends JavaPlugin implements CommandExecutor {

    /**
     * 目前没有完成:
     * 删除
     * 更改
     * API均已提供
     * 以下为演示
     */

    private void test() {

        PTPData p = new PointData(Bukkit.getPlayer("玩家名称"));// 新建一个点数据类
        // 添加点
        p.add("点名称");
        p.setPublic(true);// 是否开放
        p.setYaw(0);//设置视角
        p.setPitch(0);//设置视角
        p.setX(0); //设置位置(X)
        p.setY(0);//设置位置(Y)
        p.setZ(0);//设置位置(Z)
        p.setWorld(Bukkit.getWorld("世界名称"));//设置世界
        try {
            p.saveData();//保存数据
        } catch (IOException e) {
            e.printStackTrace();
        }

        // 改变点
        p.changePublic(true);// 是否开放
        p.changeYaw(0);//改变视角
        p.changePitch(0);//改变视角
        p.changeX(0); //改变位置(X)
        p.changeY(0);//改变位置(Y)
        p.changeZ(0);//改变位置(Z)
        p.changeWorld(Bukkit.getWorld("世界名称"));//改变世界
        try {
            p.saveData();//保存数据
        } catch (IOException e) {
            e.printStackTrace();
        }

        // 切记保存
        // 删除点
        p.del("点名称");

    }

    public static PTP ptp;
    private String pre = "§c§l[§bPTP§c§l] §f";
    private static Economy econ = null;

    @Override
    public void onEnable() {
        ptp = this;
        if (!setupEconomy()) {
            getLogger().info("Vault插件未启动！关闭插件");
            getServer().getPluginManager().disablePlugin(this);
            return;
        }
        if (!new File(getDataFolder(), "config.yml").exists()) {
            getLogger().info("配置不存在，从插件释放。。。");
            saveDefaultConfig();
        }
        Bukkit.getPluginCommand("").setExecutor(this);
        getLogger().info("启动完毕！");
    }

    @Override
    public void onDisable() {
        getLogger().info("保存数据...");
        saveAllData();
        getLogger().info("插件卸载完毕!");

    }

    private boolean setupEconomy() {
        if (getServer().getPluginManager().getPlugin("Vault") == null) {
            return false;
        }
        RegisteredServiceProvider<Economy> rsp = getServer().getServicesManager().getRegistration(Economy.class);
        if (rsp == null) {
            return false;
        }
        econ = rsp.getProvider();
        return econ != null;
    }

    public static Economy getEconomy() {
        return econ;
    }

    private void saveAllData() {
        //在此保存玩家数据
    }

    @Override
    public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
        CommandSender s = sender;
        if (args.length < 0) {
            String[] str = {pre + "§b/ptp 查看插件帮助", pre + "§b/ptp [传送点名称] 传送到已有传送点", pre + "§b/ptp buy [名称] [是否公开{true/false}（默认私有）] 购买你脚下的传送点", pre + "§b/ptp reset [传送点名称] 重置传送点至你脚下", pre + "§b/ptp del [传送点名称] 删除传送点", pre + "§b/ptp list 查看你的所有传送点"};
            new Thread(() -> {
                for (String msg : str)
                    s.sendMessage(msg);
            }).start();
            return true;
        }

        if (!(s instanceof Player)) {
            s.sendMessage(pre + "§c非玩家不能使用");
            return true;
        }

        Player p = (Player) s;

        String arg = args[0];

        switch (arg) {
            default: {
                PTPData data = getPointData(p, args[1]);
                if (data.has()) {
                    Location l = new Location(data.getWorld(), data.getX(), data.getY(), data.getZ());
                    l.setPitch(data.getPitch());
                    l.setYaw(data.getYaw());
                    l.getChunk().load(); // 预加载区块 (不可异步!)
                    p.teleport(l);
                    return true;
                } else {
                    data = findPointData(args[1]);
                    if (data == null) {
                        p.sendMessage(pre + "§c没有这个传送点或传送点未开放！");
                        return false;
                    }
                    Location l = new Location(data.getWorld(), data.getX(), data.getY(), data.getZ());
                    l.setPitch(data.getPitch());
                    l.setYaw(data.getYaw());
                    l.getChunk().load(); // 预加载区块 (不可异步!)

                    p.teleport(l);
                    return true;
                }
            }
            case "buy": {
                if (hasPoint(p.getWorld(), (int) p.getLocation().getX(), (int) p.getLocation().getY(), (int) p.getLocation().getZ())) {
                    p.sendMessage(pre + "§b这个点已经有主人了");
                    return true;
                }

                if (getEconomy().bankHas(p.getName(), getConfig().getInt("default")).transactionSuccess()) {
                    p.sendMessage(pre + "§b你没有足够的钱！");
                    return true;
                }
                if (getEconomy().bankWithdraw(p.getName(), getConfig().getInt("default")).transactionSuccess()) {
                    PTPData sj = new PointData(p);
                    sj.add(args[1]);
                    sj.setX(p.getLocation().getX());
                    sj.setY(p.getLocation().getY());
                    sj.setZ(p.getLocation().getZ());
                    sj.setWorld(p.getWorld());
                    sj.setPitch(p.getLocation().getPitch());
                    sj.setYaw(p.getLocation().getYaw());
                    if (args[2].equalsIgnoreCase("true")) {
                        sj.setPublic(true);
                    } else {
                        sj.setPublic(false);
                    }
                    try {
                        sj.saveData();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    p.sendMessage(pre + "§b购买完毕");
                    return true;
                }
            }
            case "list": {
                PTPData pd = new PointData(p);
                String[] o = (String[]) pd.getAll().toArray();
                for (String msg : o) {
                    p.sendMessage(pre + msg);
                }
            }
            case "del": {
                // 删除
            }
            case "reset": {
                // 修改
            }


        }
        return false;
    }

    private PointData findPointData(String arg) {
        File mdf = new File(PTP.ptp.getDataFolder(), "data.yml");
        if (!mdf.exists()) {
            return null;
        }
        YamlConfiguration md = YamlConfiguration.loadConfiguration(mdf);
        List<String> l;
        if (md.getList("list") == null) {
            return null;
        }
        l = (List<String>) md.getList("list");
        for (int i = 0; i < l.size(); i++) {
            Player p1 = Bukkit.getPlayer(UUID.fromString(l.get(i)));
            PTPData pd = new PointData(p1);
            if (pd.getAll() == null) {
                return null;
            }
            for (int i1 = 0; i1 < pd.getAll().size(); i1++) {
                PTPData pd1 = getPointData(p1, pd.getAll().get(i1));
                if (pd1.isPublic()) {
                    if (pd.getAll().get(i1).equalsIgnoreCase(arg)) {
                        return getPointData(p1, pd.getAll().get(i1));
                    }
                }
                break;
            }
        }
        return null;
    }

    private boolean hasPoint(World world, int x, int y, int z) {
        File mdf = new File(PTP.ptp.getDataFolder(), "data.yml");
        if (!mdf.exists()) {
            return false;
        }
        YamlConfiguration md = YamlConfiguration.loadConfiguration(mdf);
        List<String> l;
        if (md.getList("list") == null) {
            return false;
        }
        l = (List<String>) md.getList("list");
        for (int i = 0; i < l.size(); i++) {
            Player p1 = Bukkit.getPlayer(UUID.fromString(l.get(i)));
            PTPData pd = new PointData(p1);
            if (pd.getAll() == null) {
                return false;
            }
            for (int i1 = 0; i1 < pd.getAll().size(); i1++) {
                PTPData pd1 = getPointData(p1, pd.getAll().get(i1));
                if (pd1.getWorld().equals(world) && pd1.getX() == x && pd1.getY() == y && pd1.getZ() == z) {
                    return true;
                }
                break;
            }
        }
        return false;
    }

    private PointData getPointData(Player p, String name) {
        return new PointData(p, name);
    }

}
